//
//  ABUserAccount.swift
//  microblog
//
//  Created by 安波 on 15/10/30.
//  Copyright © 2015年 anbo. All rights reserved.
//

import UIKit

 /*
    ios保存数据的方式：
        1.plist
        2.偏好设置
        3.归档 （需要实现NSCoding协议）
        4.sqlite
        5.CoreData
  */

class ABUserAccount: NSObject,NSCoding {
    
    // MARK: - 属性声明
    /// 是否有账号   有账号返回true
    class func userLogin() -> Bool {
        return ABUserAccount.loadAccount() != nil
    }
    
    /// 用于调用access_token ，接口获取授权后的access_token
    var access_token: String?
    
    
    /// 当前授权用户的UID
    var uid: String?
    
    /// 友好显示名称
    var name: String?
    
    /// 用户头像地址（大图），180×180像素
    var avatar_large: String?
    
    // access_token的生命周期，单位是秒数
    /// 对于基本数据类型，不能定义为可选
    var expires_in: NSTimeInterval = 0 {
        didSet{
            expires_date = NSDate(timeIntervalSinceNow: expires_in)
            print("expires_date: \(expires_date)")
        }
    }
    /// 当前时间
    var expires_date: NSDate?
    
    /// KVC 字典转模型  前面的变量需要有值，所有我们可以应用“可选类型”来解决
    init(dict: [String: AnyObject]){
        super.init()
        
        // 将字典里面的每一个key的值，赋值给对应的模型属性
        setValuesForKeysWithDictionary(dict)
        
    }
    
//    init(dict: [String: String]){
//        // 逐一赋值
//        access_token = dict["access_token"]!
////        expires_date = dict["expires_date"] as? NSDate
//        uid = dict["uid"]!
////        expires_in = dict["expires_in"] as? Double
//        name = dict["name"]!
//        avatar_large = dict["avatar_large"]!
//    }
    
    // 当字典里面的key在模型里面没有对应的属性时，程序会崩溃，实现该方法可解决该问题
    override func setValue(value: AnyObject?, forUndefinedKey key: String) {
//        print("forUndefinedKey: \(key)")   // 打印出字典里面，在这里的找不到的Key
    }
    
    // 特别注意：方法不能调用错了
//    override func setValue(value: AnyObject?, forKey key: String) {
//        print("forUndefinedKey: \(key)")   // 打印出字典里面，在这里的找不到的Key
//    }
    
    
    // 打印字典里的所有属性
    override var description: String {
        return "access_token:\(access_token), expires_in:\(expires_in), uid:\(uid): expires_date:\(expires_date),name:\(name),avatar_large:\(avatar_large)"
    }
    
    // MARK: - 加载用户信息
    // 控制器调用这个方法，不管是成功还是失败，都需要告诉调用者
    func loadUserInfo(finish:(error: NSError?) -> ()){
        ABNetworkTools.sharedInstance.loadUserInfo { (result, error) -> () in
            print("result: \(result)")
            if error != nil || result == nil {
                finish(error: error)
                return
            }
            
            // 加载成功
            self.name = result!["name"] as? String
            self.avatar_large = result!["avatar_large"] as? String
            print(self.name)
            // 保存到沙盒
            self.saveAccount()
            
            // 同步到内存中，把当前对象赋值给内存中的userAccount
            ABUserAccount.userAccount = self
            finish(error: nil)
            
        }
    }
    
    // 类方法访问属性，属性的定义需要加 static 来修饰
    // 对象方法访问static属性，需要 类名.属性名
    /// 定义保存到沙盒的文件路径
    static let accountPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).last! + "/Account.plist"
    
    // MARK: - 保存对象
    /// 保存对象到account.plist文件
    func saveAccount(){
        // 用户对象保存到 accoun.plist文件中（直接归档）
        NSKeyedArchiver.archiveRootObject(self, toFile: ABUserAccount.accountPath)
        
    }
    
    /// 加载用户信息
//    class func loadAccount() -> ABUserAccount? {
//        
//        // 将从文件中获得的 用户信息 强转为自定义类型（解档）
//        let account = NSKeyedUnarchiver.unarchiveObjectWithFile(accountPath) as? ABUserAccount
//        return account
//    }
    
    // 定义属性
    private static var userAccount: ABUserAccount?
    
    /// 加载用户信息
    class func loadAccount() -> ABUserAccount? {
        // 判断内存有没有
        if userAccount == nil {
            // 内存中没有才来解档,并赋值给内存中的账号
            userAccount = NSKeyedUnarchiver.unarchiveObjectWithFile(accountPath) as? ABUserAccount
            
        }
        
        // 判断内存中有账号 且有效时间有效
        if userAccount != nil && userAccount?.expires_date?.compare(NSDate()) == NSComparisonResult.OrderedDescending {
            // 账号有效
//            print("账号有效")
            return userAccount
        }
        
        return nil
    }
    
    // MARK: - 归档和解档
    // 归档
    func encodeWithCoder(aCoder: NSCoder){
        aCoder.encodeObject(access_token, forKey: "access_token")
        aCoder.encodeObject(expires_date, forKey: "expires_date")
        aCoder.encodeObject(uid, forKey: "uid")
        aCoder.encodeDouble(expires_in, forKey: "expires_in")
        aCoder.encodeObject(name, forKey: "name")
        aCoder.encodeObject(avatar_large, forKey: "avatar_large")
    }
    
    // 解档   as后接“！”是强转（必须有值），as后接“？”是强转（可有可无值，是可选的）
    required init?(coder aDecoder: NSCoder){
        access_token = aDecoder.decodeObjectForKey("access_token") as? String
        expires_date = aDecoder.decodeObjectForKey("expires_date") as? NSDate
        uid = aDecoder.decodeObjectForKey("uid") as? String
        expires_in = aDecoder.decodeDoubleForKey("expires_in")
        name = aDecoder.decodeObjectForKey("name") as? String
        avatar_large = aDecoder.decodeObjectForKey("avatar_large") as? String
    }
    
}
